package com.monkeyboy.mongo_demo;

import com.mongodb.client.AggregateIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.monkeyboy.util.MongoDBAuthUtil;
import org.bson.Document;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author Gavin
 * @date 2021.01.11 12:13
 */
public class AggregateDocument {
    public static void main(String[] args) {
        AggregateDocument aggregateDocument = new AggregateDocument();
        aggregateDocument.selectDocumentAggregateHaving();
    }

    /**
     * 分组后过滤
     * $match  - having
     * db.java_coll.aggregate([{$group:{_id:'$username',totalAge:{$sum:"$age"}}},{$match:{totalAge:{$gt:10}}}])
     */
    public void selectDocumentAggregateHaving() {
        MongoCollection<Document> collection = MongoDBAuthUtil.getCollection("test", "java_coll");
        //第一个{}
        Document sum = new Document();
        sum.put("$sum", "$age");
        Document totalAge = new Document();
        totalAge.put("_id", "$username");
        totalAge.put("totalAge", sum);
        Document group = new Document();
        group.put("$group", totalAge);
        //第二个{}
        Document gt = new Document();
        gt.put("$gt", 10);
        Document age = new Document();
        age.put("totalAge", gt);
        Document match = new Document();
        match.put("$match", age);

        List<Document> list = new ArrayList<>();
        //注意list add的顺序代表着match的意以，如果match在group之前则代表where含义
        //如果在group之后则代表having含义
        list.add(group);
        list.add(match);
        AggregateIterable<Document> documents = collection.aggregate(list);
        //通过游标来访问数据
        MongoCursor<Document> cursor = documents.iterator();
        while (cursor.hasNext()) {
            Document doc = cursor.next();
            System.out.println(doc.get("totalAge"));
        }
    }

    /**
     * $match筛选 - where
     * db.java_coll.aggregate([{$match:{age:{$gt:10}}},{$group:{_id:null,totalAge:{$sum:1}}}])
     */
    public void selectDocumentAggregateWhere() {
        MongoCollection<Document> collection = MongoDBAuthUtil.getCollection("test", "java_coll");
        //第一个{}
        Document gt = new Document();
        gt.put("$gt", 10);
        Document age = new Document();
        age.put("age", gt);
        Document match = new Document();
        match.put("$match", age);
        //第二个{}
        Document sum = new Document();
        sum.put("$sum", 1);
        Document totalAge = new Document();
        totalAge.put("_id", null);
        totalAge.put("totalAge", sum);
        Document group = new Document();
        group.put("$group", totalAge);

        List<Document> list = new ArrayList<>();
        //注意list add的顺序代表着match的意以，如果match在group之前则代表where含义
        //如果在group之后则代表having含义
        list.add(match);
        list.add(group);
        AggregateIterable<Document> documents = collection.aggregate(list);
        //通过游标来访问数据
        MongoCursor<Document> cursor = documents.iterator();
        while (cursor.hasNext()) {
            Document doc = cursor.next();
            System.out.println(doc.get("totalAge"));
        }
    }

    /**
     * 分组求和 $sum
     * db.test.aggregate([{$group:{_id:'$username',totalAge:{$sum:'$age'}}}])
     */
    public void selectDocumentAggregateGroupSum() {
        MongoCollection<Document> collection = MongoDBAuthUtil.getCollection("test", "java_coll");
        Document sum = new Document();
        sum.put("$sum", "$age");
        Document totalAge = new Document();
        totalAge.put("_id", "$username");
        totalAge.put("totalAge", sum);
        Document group = new Document();
        group.put("$group", totalAge);
        List<Document> list = new ArrayList<>();
        list.add(group);
        AggregateIterable<Document> documents = collection.aggregate(list);
        //通过游标来访问数据
        MongoCursor<Document> cursor = documents.iterator();
        while (cursor.hasNext()) {
            Document doc = cursor.next();
            System.out.println(doc.get("totalAge"));
        }
    }

    /**
     * 聚合操作 计算键值的总和 $sum
     * db.test.aggregate([{$group:{_id:null,totalAge:{$sum:"$age"}}}])
     */
    public void selectDocumentAggregateSum() {
        MongoCollection<Document> collection = MongoDBAuthUtil.getCollection("test", "java_coll");
        Document sum = new Document();
        sum.put("$sum", "$age");
        Document totalAge = new Document();
        totalAge.put("_id", null);
        totalAge.put("totalAge", sum);
        Document group = new Document();
        group.put("$group", totalAge);
        List<Document> list = new ArrayList<>();
        list.add(group);
        AggregateIterable<Document> documents = collection.aggregate(list);
        //通过游标来访问数据
        MongoCursor<Document> cursor = documents.iterator();
        while (cursor.hasNext()) {
            Document doc = cursor.next();
            System.out.println(doc.get("totalAge"));
        }
    }

    /**
     * $sum 查询文档数量
     * db.test.aggregate([{$group:{_id:null,count:{$sum:1}}}])
     * 有个技巧就是一个{}就是java中的一个Document对象
     */
    public void selectDocumentAggregateCount() {
        MongoCollection<Document> collection = MongoDBAuthUtil.getCollection("test", "java_coll");
        Document sum = new Document();
        sum.put("$sum", 1);

        Document count = new Document();
        count.put("_id", null);
        count.put("count", sum);

        Document group = new Document();
        group.put("$group", count);
        List<Document> list = new ArrayList<>();
        list.add(group);
        AggregateIterable<Document> documents = collection.aggregate(list);
        //通过游标来访问数据
        MongoCursor<Document> cursor = documents.iterator();
        while (cursor.hasNext()) {
            Document doc = cursor.next();
            System.out.println(doc.get("count"));
        }
    }
}
